#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <pthread.h>

#define NUM 3

int *p = nullptr;

// 编译选项，只能用来修饰内置类型，不能用来修饰自定义类型
// 变量存储在线程的局部域，每个线程各自有一份
__thread int g_val = 100;

struct pthreadDate
{
    std::string pthreadname;
};

std::string toHex(pthread_t tid)
{
    char buffer[128];
    snprintf(buffer, sizeof(buffer), "0x%x", tid);
    return buffer;
}

void *pthreadRoutine(void *args)
{
    pthread_detach(pthread_self());
    pthreadDate *td = static_cast<pthreadDate *>(args);
    int i = 0;
    // int time_i = 0;
    //  if (td->pthreadname == "Thread-2")
    //  {
    //      p = &time_i;
    //  }
    while (i < 10)
    {
        std::cout << "pid : " << getpid() << "tid : " << toHex(pthread_self()) << ", pthreadname : " << td->pthreadname
                  << "g_val : " << g_val << ", &g_val : " << &g_val << std::endl;
        sleep(1);
        i++;
        g_val++;
    }
}

void InitThreadDate(pthreadDate *td, int number)
{
    td->pthreadname = "Thread-" + std::to_string(number);
}

int main()
{
    pthread_t tid;
    std::vector<pthread_t> tids;
    for (int i = 0; i < NUM; i++)
    {
        pthreadDate *td = new pthreadDate;
        InitThreadDate(td, i);
        pthread_create(&tid, nullptr, pthreadRoutine, td);
        tids.push_back(tid);
        sleep(1);
    }

    sleep(1);  //确保复制成功

    // for (auto i : tids)  //线程分离
    // {
    //     pthread_detach(i);
    // }

    // std::cout << "main thread get a thread val : " << *p << "&val : " << p << std::endl;  //其他线程实际上也可以拿到其他线程独立栈上的数据

    for (int i = 0; i < tids.size(); i++)
    {
        int n = pthread_join(tid, nullptr);
        printf("n = %d, who = 0x%x, why: %s\n", n, tids[i], strerror(n));
    }

    return 0;
}